using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Caching;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Net.Mail;
using System.Text;
using System.Text.RegularExpressions;

namespace Ample
{
    public static class Helpers
    {
        private static string UserEmailRegConfirmTemplate = "~/Email Templates/UserEmailRegConfirmTemplate.txt";
        private static string AdminEmailUserRegTemplate = "~/Email Templates/AdminEmailUserRegTemplate.txt";

        private static string[] _countries = new string[]
                                                 {
                                                     "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
                                                     "Angola", "Anguilla", "Antarctica", "Antigua And Barbuda",
                                                     "Argentina",
                                                     "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
                                                     "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus",
                                                     "Belgium", "Belize", "Benin", "Bermuda", "Bhutan",
                                                     "Bolivia", "Bosnia Hercegovina", "Botswana", "Bouvet Island",
                                                     "Brazil",
                                                     "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burundi",
                                                     "Byelorussian SSR",
                                                     "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands",
                                                     "Central African Republic", "Chad", "Chile", "China",
                                                     "Christmas Island",
                                                     "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
                                                     "Cook Islands",
                                                     "Costa Rica", "Cote D'Ivoire", "Croatia", "Cuba", "Cyprus",
                                                     "Czech Republic", "Czechoslovakia", "Denmark", "Djibouti",
                                                     "Dominica",
                                                     "Dominican Republic", "East Timor", "Ecuador", "Egypt",
                                                     "El Salvador",
                                                     "England", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia",
                                                     "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France",
                                                     "Gabon", "Gambia", "Georgia", "Germany", "Ghana",
                                                     "Gibraltar", "Great Britain", "Greece", "Greenland", "Grenada",
                                                     "Guadeloupe", "Guam", "Guatemela", "Guernsey", "Guiana",
                                                     "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Heard Islands",
                                                     "Honduras", "Hong Kong", "Hungary", "Iceland", "India",
                                                     "Indonesia", "Iran", "Iraq", "Ireland", "Isle Of Man",
                                                     "Israel", "Italy", "Jamaica", "Japan", "Jersey",
                                                     "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, South",
                                                     "Korea, North", "Kuwait", "Kyrgyzstan", "Lao People's Dem. Rep.",
                                                     "Latvia",
                                                     "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein",
                                                     "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar",
                                                     "Malawi", "Malaysia", "Maldives", "Mali", "Malta",
                                                     "Mariana Islands", "Marshall Islands", "Martinique", "Mauritania",
                                                     "Mauritius",
                                                     "Mayotte", "Mexico", "Micronesia", "Moldova", "Monaco",
                                                     "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar",
                                                     "Namibia", "Nauru", "Nepal", "Netherlands", "Netherlands Antilles",
                                                     "Neutral Zone", "New Caledonia", "New Zealand", "Nicaragua",
                                                     "Niger",
                                                     "Nigeria", "Niue", "Norfolk Island", "Northern Ireland", "Norway",
                                                     "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea",
                                                     "Paraguay", "Peru", "Philippines", "Pitcairn", "Poland",
                                                     "Polynesia", "Portugal", "Puerto Rico", "Qatar", "Reunion",
                                                     "Romania", "Russian Federation", "Rwanda", "Saint Helena",
                                                     "Saint Kitts",
                                                     "Saint Lucia", "Saint Pierre", "Saint Vincent", "Samoa",
                                                     "San Marino",
                                                     "Sao Tome and Principe", "Saudi Arabia", "Scotland", "Senegal",
                                                     "Seychelles",
                                                     "Sierra Leone", "Singapore", "Slovakia", "Slovenia",
                                                     "Solomon Islands",
                                                     "Somalia", "South Africa", "South Georgia", "Spain", "Sri Lanka",
                                                     "Sudan", "Suriname", "Svalbard", "Swaziland", "Sweden",
                                                     "Switzerland", "Syrian Arab Republic", "Taiwan", "Tajikista",
                                                     "Tanzania",
                                                     "Thailand", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago",
                                                     "Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands",
                                                     "Tuvalu",
                                                     "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom",
                                                     "United States",
                                                     "Uruguay", "Uzbekistan", "Vanuatu", "Vatican City State",
                                                     "Venezuela",
                                                     "Vietnam", "Virgin Islands", "Wales", "Western Sahara", "Yemen",
                                                     "Yugoslavia", "Zaire", "Zambia", "Zimbabwe"
                                                 };

        private static string[] _states = new string[]
                                              {
                                                  "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
                                                  "Connecticut",
                                                  "District of Columbia", "Delaware", "Florida", "Georgia", "Hawaii",
                                                  "Idaho",
                                                  "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana",
                                                  "Maine", "Maryland",
                                                  "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri",
                                                  "Montana", "Nebraska",
                                                  "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York",
                                                  "North Carolina", "North Dakota",
                                                  "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
                                                  "South Carolina", "South Dakota","Tennessee", "Texas", "Utah", "Vermont",
                                                  "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming",
                                                  "Alberta", "British Columbia", "Manitoba", "New Brunswick", "Newfoundland and Labrador",
                                                  "Northwest Territories", "Nova Scotia", "Nunavut", "Ontario", "Prince Edward Island",
                                                  "Quebec", "Saskatchewan", "Yukon"} ;
        /// <summary>
        /// Returns an array with all countries
        /// </summary>     
        public static StringCollection GetCountries()
        {
            StringCollection countries = new StringCollection();
            countries.AddRange(_countries);
            return countries;
        }
        public static SortedList GetCountries(bool insertEmpty)
        {
            SortedList countries = new SortedList();
            if (insertEmpty)
                countries.Add("", "Please select one...");
            foreach (String country in _countries)
                countries.Add(country, country);
            return countries;
        }

        public static StringCollection GetStates()
        {
            StringCollection states = new StringCollection();
            states.AddRange(_states);
            return states;
        }

        public static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://msdn.microsoft.com/en-us/library/system.web.security.membershipcreatestatus.aspx for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "Username already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A username for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }

        /// <summary>
        /// Converts the input plain-text to HTML version, replacing carriage returns
        /// and spaces with <br /> and &nbsp;
        /// </summary>
        public static string ConvertToHtml(string content)
        {
            content = HttpUtility.HtmlEncode(content);
            content = content.Replace("  ", "&nbsp;&nbsp;").Replace(
               "\t", "&nbsp;&nbsp;&nbsp;").Replace("\n", "<br/>");
            return content;
        }

        public static string GetHostAddress()
        {
            string scheme = HttpContext.Current.Request.Url.Scheme;

            string hostname = HttpContext.Current.Request.Url.Authority;

            return scheme + @"://" + hostname + HttpContext.Current.Request.ApplicationPath;
        }
    
        public static void AdminEmailUserRegistered(string username, string userEmail, Page sendingPage)
        {
            string subject = "Ample International Web: New User Registered";

            ListDictionary replacements = new ListDictionary();

            replacements.Add("<% USERNAME %>", username);
            replacements.Add("<% LINK %>", "<a href=" + GetHostAddress() + @"/Admin/Users/EditUser.aspx?Username=" + username + ">" + username + "</a>");

            string [] adminUsers = Roles.GetUsersInRole("Administrators");

            MailAddressCollection mac = new MailAddressCollection();
            foreach (var s in adminUsers)
            {
                MembershipUser mu = Membership.GetUser(s);
                
                mac.Add(mu.Email);
            }

            Email(AdminEmailUserRegTemplate, string.Empty, sendingPage, replacements, Globals.Settings.Ample.EMail,
                  Globals.Settings.Ample.DisplayName, mac, subject);
        }

        public static void AdminEmailUserRegisterApproval(string username, string userEmail, Page sendingPage)
        {
            string subject = "Ample International Web: New User Registration verified";

            var replacements = new ListDictionary();

            MembershipUser mu = Membership.GetUser(username);
            string password = mu.ResetPassword();
            
            replacements.Add("<% USERNAME %>", username);
            replacements.Add("<% PASSWORD %>", password);
           
            replacements.Add("<% LINK %>", "<a href=" + GetHostAddress() + "> Ample International Web </a>");
            
            var mac = new MailAddressCollection();
            mac.Add(userEmail);

            Email(UserEmailRegConfirmTemplate, string.Empty, sendingPage, replacements, Globals.Settings.Ample.EMail,
                  Globals.Settings.Ample.DisplayName, mac, subject);
        }

        public static bool Email(string bodyFilePath, string uploadingPath, Page sendingPage, ListDictionary replacements,
            string fromEmail, string fromUsername, MailAddressCollection mac , string subject)
        {
            SmtpClient smtpClient = new SmtpClient();

            MailDefinition md = new MailDefinition();

            //specify the location of template
            md.BodyFileName = bodyFilePath;
            //Build replacement collection to replace fields in template
            
            replacements.Add("<%DATETIME%>", DateTime.Now.ToShortDateString());
            replacements.Add("<%WEBSITE%>", fromEmail);

            MailMessage mail = md.CreateMailMessage( mac.ToString(), replacements, sendingPage);

            mail.From = new MailAddress(fromEmail, fromUsername);
            mail.Subject = subject;
            
            //mail.Body = body;
            mail.IsBodyHtml = true;

            //foreach (BPG_Basic.OrderedProductRow opr in opdt.Rows)
            //{
            //    string determinedName = BPG.Helpers.DetermineAvailableName(uploadingPath, "Attachment.temp");

            //    if (!opr.IsDefaultPictureNull())
            //    {
            //        System.IO.File.WriteAllBytes(determinedName, opr.DefaultPicture);

            //        System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType();
            //        ct.MediaType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
            //        //ct.Name = opr.ca;

            //        Attachment at = new Attachment(determinedName, ct);
            //        mail.Attachments.Add(at);
            //    }
            //}

#if(DEBUG)
            smtpClient.EnableSsl = true;
#endif
            Object userState = new object();
            bool success = false;
            try
            {
                smtpClient.SendAsync(mail, userState);
                success = true;
            }
            catch
            {
            }

            return success;
        }

        public static void HandleProfileException(System.Exception e, ref Literal ExceptionDetails)
        {
            if (e != null)
            {
                // Display a user-friendly message
                ExceptionDetails.Visible = true;
                ExceptionDetails.Text = "There was a problem updating the Profile.";
                if (e is System.Data.Common.DbException)
                {
                    if (e.Message.Contains("FK_"))
                        ExceptionDetails.Text += "Before inserting the item, its associated item must be removed from the database.";
                    else if (e.Message.Contains("IX_"))
                        ExceptionDetails.Text += "This name already exists.";
                    else if (e.Message.Contains("NULL"))
                        ExceptionDetails.Text += "NULL value cannot be inserted";
                    else
                        ExceptionDetails.Text += "Our database is currently experiencing problems." + "Please try again later.";
                }
                else if (e is System.ApplicationException)
                {
                    if (e.Message.Contains("FK_"))
                        ExceptionDetails.Text += "Before inserting the item, its associated item must be removed from the database.";
                    else if (e.Message.Contains("IX_"))
                        ExceptionDetails.Text += "This name already exists.";
                    else if (e.Message.Contains("NULL"))
                    {
                        Match m = Regex.Match(e.Message, @"into column (.*), table");
                        ExceptionDetails.Text += string.Format(" NULL value cannot be inserted in {0}", m.Groups[1] );
                    }
                    else
                        ExceptionDetails.Text += "Our database is currently experiencing problems." + "Please try again later.";
                }
                else if (e is NoNullAllowedException)
                    ExceptionDetails.Text += "There are one or more required fields that are missing.";
                else if (e is ArgumentException)
                {
                    string paramName = ((ArgumentException)e).ParamName;
                    ExceptionDetails.Text += string.Concat("The ", paramName, " value is illegal.");
                }
                else if (e is ApplicationException)
                    ExceptionDetails.Text += e.Message;
            }
        }

        
    }
}
